package org.jeecg.modules.demo.pointcount.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.demo.moenydata.uitils.GamesEnum;
import org.jeecg.modules.demo.moenydata.uitils.TimeUtil;
import org.jeecg.modules.demo.pointcount.entity.*;
import org.jeecg.modules.demo.pointcount.redis.util.Config;
import org.jeecg.modules.demo.pointcount.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author yw
 * @Date 2021/3/8 16:05
 */
@Api(tags="打点统计")
@RestController
@RequestMapping("/point/count")
@Slf4j
public class PointCountController extends JeecgController<CheckData, ICheckDataService> {



    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IPonintCountService ponintCountService;

    @Autowired
    private IOnlineDataService onlineDataService;

    @Autowired
    RedisUtil redisUtil;

    @AutoLog(value = "打点统计-分页列表查询")
    @ApiOperation(value="打点统计-分页列表查询", notes="打点统计-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(PointCount pointCount,
                                   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                   @RequestParam(name = "num",required = false) String num,
                                   HttpServletRequest req) {
        /** old start */
//        String tbName=GamesEnum.getTableName(num);
//        if(tbName.equals("erro")){
//            return Result.error("没有对应该参数的库表!");
//        }
//        tbName+="eventdata";
//        pointCount.setTableName(tbName);
//		Map<String, String[]> parameterMap=req.getParameterMap();
//        //循环遍历查询条件
//		/*for(String key:parameterMap.keySet()){
//			String value = parameterMap.get(key)[0].toString();//
//			System.out.println("key:"+key+" vlaue:"+value);
//		}*/
//        pointCount.setPageNo(pageNo*pageSize-pageSize);
//        pointCount.setPageSize(pageNo*pageSize);
//		if(parameterMap.containsKey("system")){
//		    pointCount.setSystem(parameterMap.get("system")[0].toString());
//        }
//        if(parameterMap.containsKey("begintime")){
//            pointCount.setBegintime(parameterMap.get("begintime")[0].toString());
//        }
//        if(parameterMap.containsKey("endtime")){
//            pointCount.setEndtime(parameterMap.get("endtime")[0].toString());
//        }
//        Integer total=ponintCountService.getPointListCount(pointCount);
//        if(total==0){
//            Map<String,Object> map=new HashMap<String,Object>();
//            return Result.error("无数据");
//        }
//        List<PointCount> numList=ponintCountService.getNumList(pointCount);//表头集合
//		List<PointCount> pageList=ponintCountService.getPointList(numList,pointCount);//数据集合
//		Map<String,Object> map=new HashMap<String,Object>();
//		map.put("records",pageList);
//		map.put("numList",numList);
//		map.put("total",total);
//        return Result.OK(map);
        /** old end */

        /** zrikka start */
        String tbName=GamesEnum.getTableName(num);
        if(tbName.equals("erro")){
            return Result.error("没有对应该参数的库表!");
        }
        tbName+="eventdata";
        pointCount.setTableName(tbName);// 设置表名
        Map<String, String[]> parameterMap=req.getParameterMap();
        // 分页设置
        pointCount.setPageNo(pageNo*pageSize-pageSize);
        pointCount.setPageSize(pageNo*pageSize);
        // 获取查询条件参数
        if(parameterMap.containsKey("system")){
            pointCount.setChannel(parameterMap.get("system")[0].toString());
        }
        if(parameterMap.containsKey("begintime")){
            pointCount.setBegintime(parameterMap.get("begintime")[0].toString());
        }
        if(parameterMap.containsKey("endtime")){
            pointCount.setEndtime(parameterMap.get("endtime")[0].toString());
        }
        pointCount.setType("0");
        // 查询数据总数
        Integer total = ponintCountService.queryPointCount(pointCount);
        if(total==0){
            Map<String,Object> map=new HashMap<String,Object>();
            return Result.error("无数据");
        }

        List<PointCount> numList=ponintCountService.getNumList(pointCount);//表头集合
        // 查询数据
        List<PointCount> pageList=ponintCountService.queryPointData(pointCount);
        for(PointCount point : pageList){
            point.settingNum();
        }
        // 处理返回数据
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("records",pageList);
        map.put("numList",numList);
        map.put("total",total);
        return Result.OK(map);
        /** zrikka end */
    }

    @AutoLog(value = "新人打点统计-分页列表查询")
    @ApiOperation(value="新人打点统计-分页列表查询", notes="新人打点统计-分页列表查询")
    @GetMapping(value = "/newUserList")
    public Result<?> queryNewUserPageList(PointCount pointCount,
                                   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                   @RequestParam(name = "num",required = false) String num,
                                   HttpServletRequest req) {
        /** old start */
//        String tbName=GamesEnum.getTableName(num);
//        if(tbName.equals("erro")){
//            return Result.error("没有对应该参数的库表!");
//        }
//        tbName+="eventdata";
//        pointCount.setTableName(tbName);
//        Map<String, String[]> parameterMap=req.getParameterMap();
//        //循环遍历查询条件
//		/*for(String key:parameterMap.keySet()){
//			String value = parameterMap.get(key)[0].toString();//
//			System.out.println("key:"+key+" vlaue:"+value);
//		}*/
//        pointCount.setPageNo(pageNo*pageSize-pageSize);
//        pointCount.setPageSize(pageNo*pageSize);
//        if(parameterMap.containsKey("system")){
//            pointCount.setSystem(parameterMap.get("system")[0].toString());
//        }
//        if(parameterMap.containsKey("begintime")){
//            pointCount.setBegintime(parameterMap.get("begintime")[0].toString());
//        }
//        if(parameterMap.containsKey("endtime")){
//            pointCount.setEndtime(parameterMap.get("endtime")[0].toString());
//        }
//        Integer total=ponintCountService.getNewUserPointListCount(pointCount);
//        if(total==0){
//            Map<String,Object> map=new HashMap<String,Object>();
//            return Result.error("无数据");
//        }
//        List<PointCount> numList=ponintCountService.getNewUserNumList(pointCount);//表头集合
//        List<PointCount> pageList=ponintCountService.getNewUserPointList(numList,pointCount);//数据集合
//        Map<String,Object> map=new HashMap<String,Object>();
//        map.put("records",pageList);
//        map.put("numList2",numList);
//        map.put("total",total);
//        return Result.OK(map);
        /** old end */

        /** zrikka start */
        String tbName=GamesEnum.getTableName(num);
        if(tbName.equals("erro")){
            return Result.error("没有对应该参数的库表!");
        }
        tbName+="eventdata";
        pointCount.setTableName(tbName);
        Map<String, String[]> parameterMap=req.getParameterMap();
        // 分页设置
        pointCount.setPageNo(pageNo*pageSize-pageSize);
        pointCount.setPageSize(pageNo*pageSize);
        // 设置查询条件
        if(parameterMap.containsKey("system")){
            pointCount.setChannel(parameterMap.get("system")[0].toString());
        }
        if(parameterMap.containsKey("begintime")){
            pointCount.setBegintime(parameterMap.get("begintime")[0].toString());
        }
        if(parameterMap.containsKey("endtime")){
            pointCount.setEndtime(parameterMap.get("endtime")[0].toString());
        }
        pointCount.setType("1");
        // 查询数据总数
        Integer total = ponintCountService.queryPointCount(pointCount);
        if(total==0){
            Map<String,Object> map=new HashMap<String,Object>();
            return Result.error("无数据");
        }
        List<PointCount> numList=ponintCountService.getNewUserNumList(pointCount);//表头集合
        // 查询数据
        List<PointCount> pageList=ponintCountService.queryPointData(pointCount);
        for(PointCount point : pageList){
            point.settingNum();
        }
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("records",pageList);
        map.put("numList2",numList);
        map.put("total",total);
        return Result.OK(map);
        /** zrikka end */
    }

    /**
     *   添加
     * @param id 通过id判断实际使用的表
     * @param param
     * @return
     */
    @AutoLog(value = "打点统计添加-对接前端")
    @ApiOperation(value="打点统计-添加对接前端", notes="打点统计-添加对接前端")
    @PostMapping(value = "/addJson",produces = "application/json;charset=utf-8")
    public Result<?> addJson(@RequestBody String param,
                             @RequestParam(value="id", required = false) String id,
                             @RequestParam(value="num", required = false,defaultValue = "301") String num) {
        String result="操作成功!";
        String tbName=GamesEnum.getTableName(num);
        if(tbName.equals("erro")){
            return Result.error("没有对应该参数的库表!");
        }
        if(param.indexOf("auto_eject")!=-1){
            return Result.error("无效数据,不写入！");
        }
        //解析为json格式
        JSONObject jsontx= JSON.parseObject(param);
        String dataName=jsontx.getString("Data");
        String sourceId=jsontx.getString("openid");
        String channel=jsontx.getString("channel");
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time=formatter.format(new Date());

        try {
        switch (id){
            case "1":
                CheckData checkData=(CheckData)JSONObject.toJavaObject(jsontx,CheckData.class);
                checkData.setId(null);
                checkData.setTableName(tbName+="checkdata");
                checkData.setTime(TimeUtil.dateToStamp(time));
                redisTemplate.opsForList().leftPush("checkData", checkData);
                break;
            case "2":
                OnlineData onlineData=(OnlineData)JSONObject.toJavaObject(jsontx,OnlineData.class);
                onlineData.setId(null);
                onlineData.setRegTime(TimeUtil.dateToStamp(onlineData.getRegTime()));
                String nowtime=TimeUtil.getNowTime2();
                //玩家队列名：Player_时间_数据源num_渠道_玩家id
                String userName="Player_"+nowtime+"_"+num+"_"+channel+"_"+sourceId;
                //渠道队列名(每个渠道中存放渠道名称)：Player_时间_数据源num_渠道名
                String channelName="Player_"+nowtime+"_"+num+"_channel";
                //userid渠道名（存放userid）
                String useridListForChannel="Player_"+nowtime+"_"+num+"_"+channel;

                OnlineData isExistData=(OnlineData)redisTemplate.opsForValue().get(userName);
                boolean isExistChannel=redisTemplate.hasKey(useridListForChannel);
                if(isExistData!=null){
                    Double oldTimeLong=isExistData.getDuration();
                    Double newTimeLong=onlineData.getDuration();
                    Double timeCount=oldTimeLong+newTimeLong;
                    isExistData.setDuration(timeCount);
                    isExistData.setTime(onlineData.getTime());

                }else{
                    isExistData=onlineData;
                    redisTemplate.opsForList().leftPush(useridListForChannel,sourceId);
                    if(!isExistChannel){
                        //渠道队列
                        redisTemplate.opsForList().leftPush(channelName,channel);
                    }
                }
                //玩家数据缓存
                redisTemplate.opsForValue().set(userName,isExistData);
                //redisTemplate.opsForList().leftPush(listname,jsontx.getString("Id"));
                break;
            case "3":
                SpecialEventData specialEventData=(SpecialEventData)JSONObject.toJavaObject(jsontx,SpecialEventData.class);
                specialEventData.setId(null);
                specialEventData.setTableName(tbName+"specialeventdata");
                specialEventData.setTime(TimeUtil.dateToStamp(time));
                redisTemplate.opsForList().leftPush("specialEventData", specialEventData);
                break;
            case "4":
                /** old start */
//                EventData eventData=(EventData)JSONObject.toJavaObject(jsontx,EventData.class);
//                eventData.setId(null);
//                eventData.setTableName(tbName+"eventdata");
//                PointCount pointCount=new PointCount();
//                pointCount.setDataName(tbName+"eventdata");
//                redisTemplate.opsForList().leftPush("pointcountall", eventData);
//                redisTemplate.opsForList().leftPush("pointcounth5", eventData);
//                redisTemplate.opsForList().leftPush("pointcountaz", eventData);
//                redisTemplate.opsForList().leftPush("pointcount", eventData);
//                redisTemplate.opsForList().leftPush("eventData", eventData);
                /** old end */
                /** 2021-0326 zrikka start */
                EventData eventData=(EventData)JSONObject.toJavaObject(jsontx,EventData.class);
                eventData.setId(null);
                eventData.setTableName(tbName+"eventdata");
                eventData.setTime(TimeUtil.dateToStamp(time));
                redisTemplate.opsForList().leftPush("eventData", eventData);
                JSONObject json = JSON.parseObject(eventData.getDatas());
                String ctime = (String)json.get("createdat");
                ctime = ctime.substring(0,10);

                StringBuffer todayUser = new StringBuffer();
                todayUser.append(ctime);
                todayUser.append("&");
                todayUser.append(eventData.getUserId());
                String userStr = (String)redisUtil.hget(Config.POINT_TODAY_USER, todayUser.toString());
                if(10 == eventData.getEvent()){
                    // 新用户打点 记录新用户id
                    if(userStr == null || "".equals(userStr)){
                        // 新建 新用户id 集合
                        redisUtil.hset(Config.POINT_TODAY_USER, todayUser.toString(), "true");
                        Integer regNum = (Integer)redisUtil.hget(Config.POINT_TODAY_USER_NUM, ctime);
                        AtomicInteger aint = null;
                        if(regNum == null){
                            aint = new AtomicInteger(0);
                        }else {
                            aint = new AtomicInteger(regNum);
                        }
                        redisUtil.hset(Config.POINT_TODAY_USER_NUM, ctime, aint.addAndGet(1));
                    }
                }else {
                    // 用户打点
                    int type = 0;// 默认为全部用户
                    // 判断是否为 今日新用户
                    if("true".equals(userStr)){
                        type = 1;// 今日新用户
                    }
                    // ctime&tablename&channel&event&type
                    StringBuffer key = new StringBuffer();
                    key.append(ctime);
                    key.append("&");
                    key.append(eventData.getTableName());
                    key.append("&");
                    key.append(json.get("channel"));
                    key.append("&");
                    key.append(eventData.getEvent());
                    // 新注册用户需要重新计算
                    if(type == 1){
                        StringBuffer str = new StringBuffer(key.toString());
                        str.append("&");
                        str.append(1);
                        redisAddPointRecord(str.toString());
                    }
                    key.append("&");
                    key.append(0);
                    redisAddPointRecord(key.toString());
                }
                /** zrikka end */
                break;
            default:
                result="id错误，不在判断选项中！";
                break;
        }
        //线程休眠
            Thread.sleep(100);
        }catch (Exception e){
                e.printStackTrace();
        }

        return Result.OK(result);

    }

    /** zrikka start */
    public void redisAddPointRecord(String key){
        // 查询是否存在
        Integer point = (Integer)redisUtil.hget(Config.POINT_ADD_EVENT,key);
        if(point != null && !"".equals(point)){
            // 存在
            AtomicInteger aint = new AtomicInteger(point);
            redisUtil.hset(Config.POINT_ADD_EVENT,key,aint.addAndGet(1));
        }else {
            // 不存在
            redisUtil.hset(Config.POINT_ADD_EVENT,key,1);
        }
    }
    /** zrikka end */

}
